package com.jt.service;

import com.jt.vo.ImageVo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

/**
 * @author Cx
 * @stage JT Of Fourth stage
 * @creat 2020-12-01 15:24
 */
@Service
@PropertySource(value = "classpath:/properties/image.properties", encoding = "UTF-8") /* 将配置文件导入容器 */
public class FileServiceImpl implements FileService {

    @Value("${image.fileDir}")
    private String fileDir; /* 路径 */
    @Value("${image.urlPath}")
    private String urlPath; /* 设定域名地址 */

    private static Set<String> typeSet = new HashSet<>();

    static {
        /* 为静态属性赋值 可以利用配置文件动态将图片类型获取 循环遍历 */
        typeSet.add(".jpg");
        typeSet.add(".png");
        typeSet.add(".gif");
    }

    /**
     * 实现文件上传
     *
     * @param uploadFile
     * @return
     */
    @Override
    public ImageVo upload(MultipartFile uploadFile) {
        /* 1.校验图片的类型 jpg/png/gif... */
        // 1.1 获取文件名称
        String fileName = uploadFile.getOriginalFilename();
        // 全部转化为小写
        fileName = fileName.toLowerCase();
        // 1.2 获取文件后缀
        int index = fileName.lastIndexOf(".");
        // 1.3 .jpg
        String fileType = fileName.substring(index);
        // 1.4 判断是否为图片类型
        if (!typeSet.contains(fileType)) {
            return ImageVo.fail();
        }
        /* 2.校验文件是否为恶意程序 */
        // 2.1 将数据转化为图片对象
        try {
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if (width == 0 || height == 0) {
                return ImageVo.fail();
            }
            /* 3.采用分目录结构进行存储 */
            // 3.1 按照年月日[/yyyy/MM/dd/]方式进行目录划分
            String dateDir = new SimpleDateFormat("/yyyy/MM/dd/")
                    .format(new Date());
            String fileDirPath = fileDir + dateDir;
            File dirFile = new File(fileDirPath);
            // 3.2 创建目录
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }
            /* 4.避免文件重名 UUID */
            // 4.1 准备文件名称
            String uuid = UUID.randomUUID().toString()
                    .replace("-", "");
            // 4.2 动态生成文件名称 uuid.jpg
            String uuidName = uuid + fileType;
            // 4.3 实现文件上传
            File realFile = new File(fileDirPath + uuidName);
            uploadFile.transferTo(realFile);
            String url = urlPath + dateDir + uuidName;
            return ImageVo.success(url, width, height);
        } catch (IOException e) {
            e.printStackTrace();
            return ImageVo.fail();
        }
    }

}
